//! 语句表达式

use super::node::Node;
use crate::parser::expression_statement::ExpressionStatement;
use crate::parser::letstatement::LetStatement;
use crate::parser::node::NodeRoot;
use crate::parser::return_statement::ReturnStatement;
use std::{fmt::Debug, mem::transmute};

pub trait Statement: Debug {
    fn cast_to_node(&self) -> &dyn Node;
}

pub fn statement_obj_to_type<T: Statement>(o: &dyn Statement) -> &T {
    unsafe {
        let ptr = transmute::<&dyn Statement, (*const T, *const ())>(o);
        &*ptr.0
    }
}

impl Clone for Box<dyn Statement> {
    fn clone(&self) -> Self {
        match self.cast_to_node().get_type() {
            "LetStatement" => {
                let let_stmt = statement_obj_to_type::<LetStatement>(self.as_ref());
                Box::new(let_stmt.clone())
            }
            "ReturnStatement" => {
                let r = statement_obj_to_type::<ReturnStatement>(self.as_ref());
                Box::new(r.clone())
            }
            "ExpressionStatement" => {
                let e = statement_obj_to_type::<ExpressionStatement>(self.as_ref());
                Box::new(e.clone())
            }
            a => panic!("不支持的语句: {}", a),
        }
    }
}

pub fn cast_to_node(exp: &dyn Statement) -> &NodeRoot {
    unsafe {
        let ptr = transmute::<&dyn Statement, (*const (), *const ())>(exp);
        let ptr2 = transmute::<*const (), *const NodeRoot>(ptr.0);
        &*ptr2
    }
}

pub fn cast_to_node_mut(exp: &mut dyn Statement) -> &mut NodeRoot {
    unsafe {
        unsafe {
            let ptr = transmute::<&dyn Statement, (*const (), *const ())>(exp);
            let ptr2 = transmute::<*mut (), *mut NodeRoot>(ptr.0 as *mut ());
            &mut *ptr2
        }
    }
}
